Skip to content

feat: Add CTAP 2.2 authenticatorSelection (0x0B) API, docs, sample, and tests#480

Open
JMarkstrom wants to merge 8 commits into
developfrom
authenticatorSelection
Open

feat: Add CTAP 2.2 authenticatorSelection (0x0B) API, docs, sample, and tests#480
JMarkstrom wants to merge 8 commits into
developfrom
authenticatorSelection

Conversation

@JMarkstrom
Copy link
Copy Markdown
Contributor

Description

Adds CTAP 2.2 authenticatorSelection (command byte 0x0B) for FIDO2 over the existing CTAP-via-APDU path: payload is the command byte only (no CBOR parameters).
SDK

  • Add CtapConstants.CtapAuthenticatorSelectionCmd and AuthenticatorSelectionCommand / AuthenticatorSelectionResponse.
  • Add Fido2Session.TryAuthenticatorSelection using TouchFingerprintTask and KeyEntryRequest.TouchRequest.
  • Map CTAP OPERATION_DENIED to a dedicated ResponseStatusMessages string for clearer sample/UI text.
    FIDO2 sample
  • New menu entry and Fido2AuthenticatorSelection helper (HID FIDO enumeration, touch to select, InvalidCommand handling).
  • Extend Fido2KeyCollectorOperation and Fido2SampleKeyCollector for authenticator-selection touch messaging; update run wiring and YubiKey auto-pick where needed.
    Docs
  • Document the command in fido2-commands.md and add apdu/authenticator-selection.md; cross-link from fido2-touch-notification.md.
  • Clarify availability (CTAP 2.2), error handling (INVALID_COMMAND, OPERATION_DENIED vs USER_ACTION_TIMEOUT), and typical YubiKey UX (timeout vs explicit deny).
    Tests
  • Unit tests for APDU construction and response status mapping; inline comments aligned with nearby FIDO2 command tests.
    Fixes: (none — add Fixes #123 if you have an issue)

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How has this been tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

Test configuration:

  • OS version: Windows 11
  • Firmware version: 5.6.x, 5.7.x
  • Yubikey model[^1]: YubiKey 5C NFC, YubiKey BIO, YubiKey BIO MPE

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have run dotnet format to format my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 15, 2026

Test Results: Windows

    2 files      2 suites   43s ⏱️
4 123 tests 4 101 ✅ 22 💤 0 ❌
4 125 runs  4 103 ✅ 22 💤 0 ❌

Results for commit abc6cdd.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 15, 2026

Test Results: Ubuntu

    2 files      2 suites   1m 9s ⏱️
4 115 tests 4 093 ✅ 22 💤 0 ❌
4 117 runs  4 095 ✅ 22 💤 0 ❌

Results for commit abc6cdd.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 15, 2026

Test Results: MacOS

    4 files      4 suites   48s ⏱️
4 097 tests 4 094 ✅ 3 💤 0 ❌
4 099 runs  4 096 ✅ 3 💤 0 ❌

Results for commit abc6cdd.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • Yubico.YubiKey/src/Resources/ResponseStatusMessages.Designer.cs: Language not supported

Comment thread docs/users-manual/application-fido2/fido2-commands.md Outdated
Comment thread docs/users-manual/application-fido2/apdu/authenticator-selection.md Outdated
Comment thread Yubico.YubiKey/src/Yubico/YubiKey/Fido2/Fido2Session.AuthenticatorSelection.cs Outdated
@DennisDyallo
Copy link
Copy Markdown
Collaborator

@claude Can you address the findings/issues mentioned by @DennisDyallo and @Copilot in this PR?

@claude
Copy link
Copy Markdown

claude Bot commented May 18, 2026

Claude finished @DennisDyallo's task in 2m 33s —— View job


Addressed Copilot Review Findings

All five issues raised by Copilot have been fixed in commit e0f4ec3:

  • Fido2AuthenticatorSelection.cs — Fixed early return on InvalidCommand. The loop now continues to the next YubiKey when one doesn't support CTAP 2.2, tracking unsupported devices with an anyUnsupported flag. The "does not support CTAP 2.2" message is shown only after all keys have been tried.
  • fido2-commands.md:623 — Grammar: "All YubiKey with""All YubiKeys with"
  • apdu/authenticator-selection.md:50 — Typo: "ifUser Presence""if User Presence"
  • Fido2Session.AuthenticatorSelection.cs:21 — Removed double space: "single or multi-YubiKey""single or multi-YubiKey"
  • AuthenticatorSelectionResponseTests.cs — Replaced both hardcoded 0x6F literals with SW1Constants.NoPreciseDiagnosis (already imported via Yubico.Core.Iso7816)
    |

- Continue iterating YubiKeys on InvalidCommand instead of returning early;
  report unsupported-firmware message only after all devices are tried
- Replace hardcoded SW1 literal 0x6F with SW1Constants.NoPreciseDiagnosis in tests
- Fix double space in Fido2Session.AuthenticatorSelection.cs header comment
- Fix grammar: "All YubiKey" → "All YubiKeys" in fido2-commands.md
- Fix typo: "ifUser" → "if User" in authenticator-selection.md

Co-authored-by: Dennis Dyallo <DennisDyallo@users.noreply.github.com>
@DennisDyallo
Copy link
Copy Markdown
Collaborator

@equijano21 here are some doc changes and feature that might interest you :)

@DennisDyallo
Copy link
Copy Markdown
Collaborator

@claude can you change the order of this, so that Reset and Exit are the last menu items? make sure to verify all code paths,

What do you want to do?
1 - ListYubiKeys
2 - ChooseYubiKey
3 - SetPin
4 - ChangePin
5 - VerifyPin
6 - VerifyUv
7 - MakeCredential
8 - GetAssertion
9 - ListCredentials
10 - UpdateCredentialUserInfo
11 - DeleteCredential
12 - RetrieveLargeBlobData
13 - StoreLargeBlobData
14 - DeleteLargeBlobData
15 - GetBioInfo
16 - EnrollFingerprint
17 - SetBioTemplateFriendlyName
18 - RemoveBioEnrollment
19 - EnableEnterpriseAttestation
20 - ToggleAlwaysUv
21 - SetPinConfig
22 - Reset
23 - AuthenticatorSelection
24 - Exit

@claude
Copy link
Copy Markdown

claude Bot commented May 18, 2026

Claude finished @DennisDyallo's task in 3m 50s —— View job


Reordered Menu Items (Reset & Exit Last)

  • Read menu-related source files
  • Identify all code paths referencing menu items
  • Reorder enum so AuthenticatorSelection precedes Reset and Exit
  • Update the "automatic authentication" banner guard
  • Verify all switch/dispatch paths are consistent
  • Commit and push changes

Two files changed in commit 3adb390:

Fido2MainMenuItem.cs — Swapped the numeric values so the enum sorts correctly:

AuthenticatorSelection = 26   // was 28
Reset = 27                    // was 26
Exit = 29                     // unchanged

Since Enum.GetValues returns members sorted by numeric value, this makes the menu display order: …SetPinConfig → AuthenticatorSelection → Reset → Exit.

Fido2SampleRun.Operations.cs — Updated the "automatic authentication" banner guard. The old bound was < Reset; after the reorder that would have included AuthenticatorSelection (26 < 27). Updated to < AuthenticatorSelection so only items MakeCredential–SetPinConfig (values 10–25) get the banner, and AuthenticatorSelection, Reset, and Exit are all excluded:

if (menuItem >= Fido2MainMenuItem.MakeCredential
    && menuItem < Fido2MainMenuItem.AuthenticatorSelection)

All other code paths (RunMenuItem switch, DefaultChooseYubiKey switch, RunSample loop) use enum names rather than values, so no further changes were needed.
·

github-actions Bot and others added 3 commits May 18, 2026 14:43
…e menu

Reorder Fido2MainMenuItem enum so AuthenticatorSelection (26) appears
before Reset (27) and Exit (29), matching the intended UX where
destructive/terminal actions are listed last.

Update the "automatic authentication" banner guard in RunMenuItem to
use AuthenticatorSelection as its upper bound (instead of Reset) so
the banner is not shown for AuthenticatorSelection, Reset, or Exit.

Co-authored-by: Dennis Dyallo <DennisDyallo@users.noreply.github.com>
- Changed section title from "Authenticator selection (CTAP `authenticatorSelection`)" to "Select an authenticator".
- Updated list item from "Authenticator selection" to "Authenticator Selection".
@DennisDyallo
Copy link
Copy Markdown
Collaborator

I made some changes . What do you think @JMarkstrom @equijano21 ?

The CTAP authenticatorSelection (0x0B) command is specified in CTAP 2.1
§6.9, not CTAP 2.2, and YubiKey support for it shipped in firmware 5.5.1
(2020-11-16), not the 5.7 generation. Update all user-facing and
in-source references across the SDK, sample app, unit tests, and docs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@DennisDyallo DennisDyallo changed the title Add CTAP 2.2 authenticatorSelection (0x0B) API, docs, sample, and tests feat: Add CTAP 2.2 authenticatorSelection (0x0B) API, docs, sample, and tests May 18, 2026
@DennisDyallo DennisDyallo requested a review from equijano21 May 18, 2026 18:41
@DennisDyallo DennisDyallo added the enhancement New feature or request label May 19, 2026
@equijano21
Copy link
Copy Markdown
Contributor

Thanks! I'll review in the next couple days.

Copy link
Copy Markdown
Collaborator

@DennisDyallo DennisDyallo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!


### Available

YubiKeys with FIDO2 firmware `5.5.1` or later. The underlying command, `authenticatorSelection` (0x0B), is specified in [CTAP 2.1 §6.9](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
YubiKeys with FIDO2 firmware `5.5.1` or later. The underlying command, `authenticatorSelection` (0x0B), is specified in [CTAP 2.1 §6.9](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html).
YubiKeys with FIDO2 firmware `5.5.1` or later. The underlying command, `authenticatorSelection` (0x0B), is specified in [CTAP 2.1 §6.9](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#authenticatorSelection).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linking directly to section 6.9.

Comment on lines +30 to +31
/// Per the CTAP specification, after a successful selection the platform should send cancel
/// to other authenticators. This SDK does not manage multiple devices; callers orchestrate that.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming this means CTAPHID_CANCEL (0x11). How does a YubiKey receive this command and what does it do after?

Comment on lines +25 to +26
/// Requests User Presence (UP) on this YubiKey so the user can select it for intended use
/// (CTAP 2.1 §6.9 <c>authenticatorSelection</c>, command byte 0x0B). Requires YubiKey firmware 5.5.1 or later.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Requests User Presence (UP) on this YubiKey so the user can select it for intended use
/// (CTAP 2.1 §6.9 <c>authenticatorSelection</c>, command byte 0x0B). Requires YubiKey firmware 5.5.1 or later.
/// Requests User Presence (UP) on the connected YubiKey so the user may indicate their intention to use the YubiKey by touching it. This method can be useful in situations where a user has more than one YubiKey and the application needs to determine which key to use for a subsequent FIDO2 operation.
/// (CTAP 2.1 §6.9 <c>authenticatorSelection</c>, command byte 0x0B). Requires YubiKey firmware 5.5.1 or later.


## Authenticator selection

Request user presence (UP) so the user can indicate _which_ authenticator to use, for example when more than one YubiKey is connected.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Request user presence (UP) so the user can indicate _which_ authenticator to use, for example when more than one YubiKey is connected.
Request user presence (UP) so the user can indicate _which_ authenticator to use for a subsequent operation. This can be useful in situations where more than one YubiKey is connected.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broke this into two sentences because the original read weirdly to me.

Comment on lines +80 to +85
> [!NOTE]
> On the YubiKey, the only user affordance is touch to approve, or no touch until the
> operation times out. There is no separate deny or cancel control on the security key
> itself, so when the user does not complete UP you will usually see
> `CTAP2_ERR_USER_ACTION_TIMEOUT`, not an explicit denial. `CTAP2_ERR_OPERATION_DENIED`
> may be returned if the user engages a platform dialog to cancel the request.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> [!NOTE]
> On the YubiKey, the only user affordance is touch to approve, or no touch until the
> operation times out. There is no separate deny or cancel control on the security key
> itself, so when the user does not complete UP you will usually see
> `CTAP2_ERR_USER_ACTION_TIMEOUT`, not an explicit denial. `CTAP2_ERR_OPERATION_DENIED`
> may be returned if the user engages a platform dialog to cancel the request.
> [!NOTE]
> On the YubiKey, the user can either touch the key to select it or wait for the
> operation to time out—there is no separate deny or cancel control on the security key
> itself. When the user does not complete UP you will usually see
> `CTAP2_ERR_USER_ACTION_TIMEOUT`. However, `CTAP2_ERR_OPERATION_DENIED`
> may be returned if the user engages a platform dialog to cancel the request.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So would the platform dialog be sending the CTAPHID_CANCEL (0x11) command?

namespace Yubico.YubiKey.Fido2.Commands
{
/// <summary>
/// Ask the authenticator for User Presence (UP) so the user can select this YubiKey.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just use the same summary as the session method:

Requests User Presence (UP) on the connected YubiKey so the user may indicate their intention to use the YubiKey by touching it. This method can be useful in situations where a user has more than one YubiKey and the application needs to determine which key to use for a subsequent FIDO2 operation.

@DennisDyallo
Copy link
Copy Markdown
Collaborator

@claude Please apply @equijano21 suggestions and push. Leave her questions as pending response from team

fyi @JMarkstrom

@claude
Copy link
Copy Markdown

claude Bot commented May 21, 2026

Claude finished @DennisDyallo's task in 1m 52s —— View job


Applied all of @equijano21's code suggestions in commit abc6cdd. @equijano21's questions are left open for the team.

Tasks

  • Gather context and identify suggestions
  • Read affected files
  • Apply suggestions to docs/users-manual/application-fido2/fido2-commands.md (lines 619, 623)
  • Apply suggestions to docs/users-manual/application-fido2/apdu/authenticator-selection.md (line 85)
  • Apply suggestions to Yubico.YubiKey/src/Yubico/YubiKey/Fido2/Fido2Session.AuthenticatorSelection.cs (line 26)
  • Apply suggestions to Yubico.YubiKey/src/Yubico/YubiKey/Fido2/Commands/AuthenticatorSelectionCommand.cs (line 20)
  • Commit and push changes

Summary of changes

File Change
fido2-commands.md:619 Split description into two sentences: "…for a subsequent operation. This can be useful…"
fido2-commands.md:623 Added #authenticatorSelection anchor to CTAP 2.1 §6.9 link
apdu/authenticator-selection.md:80–85 Rewrote NOTE block for clarity (touch-or-timeout phrasing, "However," instead of comma-joined sentence)
Fido2Session.AuthenticatorSelection.cs:25 Expanded <summary> to match the suggested wording about user intention and multi-YubiKey scenarios
AuthenticatorSelectionCommand.cs:20 Aligned <summary> with session method summary

Pending questions for the team (@JMarkstrom / @equijano21):

  • Fido2Session.AuthenticatorSelection.cs:31 — Does the CTAP spec send CTAPHID_CANCEL (0x11) to other authenticators after a successful selection, and how does the YubiKey handle that?
  • apdu/authenticator-selection.md:85 — Does the platform dialog cancel by sending CTAPHID_CANCEL (0x11)?

- fido2-commands.md: rewrite authenticator selection description as two sentences; add #authenticatorSelection anchor to CTAP 2.1 §6.9 link
- apdu/authenticator-selection.md: rewrite NOTE block for clarity
- Fido2Session.AuthenticatorSelection.cs: expand summary XML doc
- AuthenticatorSelectionCommand.cs: align summary with session method

Co-authored-by: Dennis Dyallo <DennisDyallo@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Code Coverage

Package Line Rate Branch Rate Complexity Health
Yubico.Core 53% 48% 1584
Yubico.YubiKey 50% 45% 7203
Summary 50% (12941 / 25630) 46% (3164 / 6930) 8787

Minimum allowed line rate is 40%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Development

Successfully merging this pull request may close these issues.

4 participants